/*
 *  Copyright 2009 Advanced Industrial Science and Technology (AIST).
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

/*! \file
 *  \brief
 */
#pragma onece

#include <thrust/graph/graph_traits.hpp>
#include <thrust/graph/visitors.hpp>
#include <thrust/graph/properties.hpp>

#include <thrust/tuple.h>
#include <thrust/device_vector.h>

namespace thrust {
  
namespace graph { struct bfs_visitor_event_not_overridden {}; }
  
//=============
// bfs_visitor
class bfs_visitor {
  
public:
  __host__
  bfs_visitor()
  {
    //std::cout <<"bfs_visitor" <<std::endl;
  }
  
  __host__
  ~bfs_visitor()
  {
    //std::cout <<"~bfs_visitor" <<std::endl;
  }
  
  template <class Vertex>
  __device__
  inline graph::bfs_visitor_event_not_overridden
  initialize_vertex( Vertex u)
  {
    return graph::bfs_visitor_event_not_overridden();
  }
  
  template <class Vertex>
  __device__
  inline graph::bfs_visitor_event_not_overridden
  enter_step( Vertex u)
  {
    return graph::bfs_visitor_event_not_overridden();
  }

  template <class Vertex>
  __device__
  inline graph::bfs_visitor_event_not_overridden
  out_step( Vertex u)
  {
    return graph::bfs_visitor_event_not_overridden();
  }

  template <class Vertex>
  __device__
  inline graph::bfs_visitor_event_not_overridden
  examine_vertex( Vertex u)
  {
    return graph::bfs_visitor_event_not_overridden();
  }
  
  template <class Vertex>
  __device__
  inline graph::bfs_visitor_event_not_overridden
  discover_vertex( Vertex u)
  {
    return graph::bfs_visitor_event_not_overridden();
  }
  
  template <class Vertex>
  __device__
  inline graph::bfs_visitor_event_not_overridden
  finish_vertex( Vertex u)
  {
    return graph::bfs_visitor_event_not_overridden();
  }

  template <class Edge>
  __device__
  inline graph::bfs_visitor_event_not_overridden
  examine_eage( Edge e)
  {
    return graph::bfs_visitor_event_not_overridden();
  }

  template <class Edge>
  __device__
  inline graph::bfs_visitor_event_not_overridden
  tree_edge( Edge e)
  {
    return graph::bfs_visitor_event_not_overridden();
  }

  template <class Edge>
  __device__
  inline graph::bfs_visitor_event_not_overridden
  non_tree_edge( Edge e)
  {
    return graph::bfs_visitor_event_not_overridden();
  }
   
  template <class Edge>
  __device__
  inline graph::bfs_visitor_event_not_overridden
  gray_target( Edge e)
  {
    return graph::bfs_visitor_event_not_overridden();
  }

  template <class Edge>
  __device__
  inline graph::bfs_visitor_event_not_overridden
  black_target( Edge e)
  {
    return graph::bfs_visitor_event_not_overridden();
  }

};

  /*template <class Visitors>
bfs_visitor<Visitors>
make_bfs_visitor( Visitors vis) {
  return bfs_visitor<Visitors>( vis);
  }*/

//=============
namespace detail {

namespace device {
      
namespace cuda {
	
template <class Graph, class Visitor>
__host__
inline void 
breadth_first_search( const Graph& g
                      , typename graph_traits<Graph>::vertex_descriptor s
                      , Visitor& vis);
	
} // end namespace cuda
  
} // end namespace device
  
} // end namespace detail
  
} // end namespace thrust

#include <thrust/graph/detail/device/cuda/breadth_first_search.inl>
